#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <memory>
#include "shaderManager.h"
#include "stringFunctions.h"
shaderManager* SM()
{
	return shaderManager::instance();
}
shaderManager::shaderManager()
{
//... perform necessary instance initializations
}
shaderManager* shaderManager::pinstance = 0;// initialize pointer


bool shaderManager::setFloat(std::string id, std::string variable, GLfloat value)
{
	for(int x=0; x<shader.size(); x++)
	{
		if(shader[x]->id.compare(id) == 0)
		{
			//std::auto_ptr<char> buf1(new char);
			//char *buf1 = new char[variable.length()]; //MEMORY LEAK ALERT BEEP BEEP BEEP
			//strcpy(buf1.get(),variable.c_str());

			//shader[x]->shader->setUniform1f(&variable[0],value);
			shader[x]->shader->setUniform1f(&variable[0],value);
			return true;
		}
	}
	std::cout << "Error could not find shader " << id << "\n";
	return false;
}
bool shaderManager::setInt(std::string id, std::string variable, GLint value)
{
	for(int x=0; x<shader.size(); x++)
	{
		if(shader[x]->id.compare(id) == 0)
		{
			shader[x]->shader->setUniform1i(&variable[0],value);
			return true;
		}
	}
	std::cout << "Error could not find shader " << id << "\n";
	return false;
}

bool shaderManager::startShader(std::string id)
{
	for(int x=0; x<shader.size(); x++)
	{
		if(shader[x]->id.compare(id) == 0)
		{
			shader[x]->shader->begin();
			return true;
		}
	}
	std::cout << "Error could not find shader " << id << "\n";
	return false;
}

bool shaderManager::stopShader(std::string id)
{
	for(int x=0; x<shader.size(); x++)
	{
		if(shader[x]->id.compare(id) == 0)
		{
			shader[x]->shader->end();
			return true;
		}
	}
	std::cout << "Error could not find shader " << id << "\n";
	return false;
}
bool shaderManager::loadShader(std::string pathVert, std::string pathFrag)
{
	shadeStruct* s = new shadeStruct();

	char *buf1 = new char[pathVert.length()];
	strcpy(buf1,pathVert.c_str());

	char *buf2 = new char[pathFrag.length()];
	strcpy(buf2,pathFrag.c_str());

	s->id = getFileName(pathVert).substr(0,getFileName(pathVert).length()-5);
	s->shader = shaderMngr.loadfromFile(buf1,buf2);
	shader.push_back(s);


	std::cout << "Shader loaded " << s->id << "\n";

	return true;
}

shaderManager* shaderManager::instance()
{
	if (!pinstance)
	{
		pinstance = new shaderManager; // create sole instance
	}
	return pinstance; // address of sole instance
}

using namespace boost::filesystem;
using namespace std;
void loadShaderDirectory(const boost::filesystem::path & directory, bool recurse_into_subdirs)
{
    directory_iterator end;

    for( directory_iterator iter(directory) ; iter != end ; ++iter )
    {
        if ( is_directory( *iter ) )
        {
            if( recurse_into_subdirs ) loadShaderDirectory(*iter, true) ;
        }
        std::stringstream s;
        s << iter->path();
        std::string out; s >> out;
		std::string fileName = getFileName(out);

		if (fileName[fileName.length()-1] == 't') //we have a vert file
		{
			std::string fragPath = out.substr(0, out.size()-5);
			fragPath += ".frag";
			SM()->loadShader(out, fragPath);

		}
    }
}